
//#include "ctl_types.hpp"
//#include "rb_types.hpp"
#include "openglpaintingarea.h"
#include <QMouseEvent>

extern const char* vertexShaderCode;
extern const char* fragmentShaderCode;

static GLfloat glWidgetWidth = 0;
static GLfloat glWidgetHeight = 0;

OpenGLPaintingArea::OpenGLPaintingArea(QWidget *parent) {
    Q_UNUSED(parent);

    canvas = new Canvas();
}

OpenGLPaintingArea::~OpenGLPaintingArea() {
    assert(canvas != NULL);
    delete canvas;
}

void OpenGLPaintingArea::installShader() {
    initializeOpenGLFunctions();
    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    const char* adapter[1];
    adapter[0] = vertexShaderCode;
    glShaderSource(vertexShaderID, 1, adapter, 0);

    adapter[0] = fragmentShaderCode;
    glShaderSource(fragmentShaderID, 1, adapter, 0);

    glCompileShader(vertexShaderID);
    glCompileShader(fragmentShaderID);

    shaderProgramID = glCreateProgram();

    glAttachShader(shaderProgramID, vertexShaderID);
    glAttachShader(shaderProgramID, fragmentShaderID);

    glLinkProgram(shaderProgramID);
    glUseProgram(shaderProgramID);

    glDeleteShader(vertexShaderID);
    glDeleteShader(fragmentShaderID);
}

Canvas *OpenGLPaintingArea::getCanvas() {
    return canvas;
}

void OpenGLPaintingArea::setGameState(const ctl_types::gaming_tag &gt) {
    gameState = gt;
}

ctl_types::gaming_tag OpenGLPaintingArea::getGameState() const {
    return gameState;
}

void OpenGLPaintingArea::initializeGL() {
    initializeOpenGLFunctions();
    installShader();

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    // set the background color : 0.0~1.0
    glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
}

void OpenGLPaintingArea::paintGL() {
    initializeOpenGLFunctions();

    // 正交投影
    glViewport(0, 0, glWidgetWidth, glWidgetHeight);
    QMatrix4x4 projection;
    projection.setToIdentity();
    projection.ortho(0.0f, glWidgetWidth, 0.0f, glWidgetHeight, -1.0f, 1.0f);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgramID, "projection"), 1, GL_FALSE, projection.data());

    // 绘制画布
    canvas->draw(shaderProgramID);
    if (gameState == ctl_types::gaming_tag::playing_game ||
        gameState == ctl_types::gaming_tag::stopped_game)
        canvas->drawUpside(shaderProgramID);
}

void OpenGLPaintingArea::resizeGL(int w, int h) {
    glWidgetWidth = width();
    glWidgetHeight = height();
    //qDebug() << "OpenGLWidget width: " << glWidgetWidth << ", height: " << glWidgetHeight;
    Q_UNUSED(w);
    Q_UNUSED(h);
}
